import { defineComponent, PropType, Ref, ref, VNode, watch } from 'vue';
import { useControlController, useNamespace } from '@ibiz-template/vue3-util';
import {
  IAppDEUIActionGroupDetail,
  IDEContextMenu,
  IDETBUIActionItem,
  IDETreeNode,
} from '@ibiz/model-core';
import './context-menu.scss';
import { ContextMenuController, ITreeNodeData } from '@ibiz-template/runtime';

export const ContextMenuControl = defineComponent({
  name: 'IBizContextMenuControl',
  props: {
    modelData: {
      type: Object as PropType<IDEContextMenu>,
      required: true,
    },
    context: { type: Object as PropType<IContext>, required: true },
    params: { type: Object as PropType<IParams>, default: () => ({}) },
    // 模式
    mode: {
      type: String as PropType<'dropdown' | 'buttons'>,
      default: 'buttons',
    },
    // 分组的行为级别
    groupLevelKeys: {
      type: Object as PropType<number[]>,
      // eslint-disable-next-line vue/require-valid-default-prop
      default: [50],
    },
    // 节点数据
    nodeData: {
      type: Object as PropType<ITreeNodeData>,
      required: true,
    },
    // 节点模型
    nodeModel: {
      type: Object as PropType<IDETreeNode>,
      required: true,
    },
  },
  setup(props, { emit }) {
    const c = useControlController(
      (...args) => new ContextMenuController(...args),
    );

    const ns = useNamespace('context-menu');

    const actionDetails = props.modelData.detoolbarItems as IDETBUIActionItem[];

    // 平铺行为
    const expandDetails: Ref<IDETBUIActionItem[]> = ref([]);

    // 分组行为
    const groupDetails: Ref<IDETBUIActionItem[]> = ref([]);

    const groupButtonRef = ref();

    const popoverVisible = ref(false);

    if (actionDetails) {
      // 转换多语言
      actionDetails?.forEach(detail => {
        if (detail.capLanguageRes && detail.capLanguageRes.lanResTag) {
          detail.caption = ibiz.i18n.t(
            detail.capLanguageRes.lanResTag,
            detail.caption,
          );
        }
        if (detail.tooltipLanguageRes && detail.tooltipLanguageRes.lanResTag) {
          detail.tooltip = ibiz.i18n.t(
            detail.tooltipLanguageRes.lanResTag,
            detail.tooltip,
          );
        }
      });

      // 根据level分组
      actionDetails.forEach(detail => {
        if (
          props.groupLevelKeys.findIndex(
            item => item === detail.actionLevel,
          ) !== -1
        ) {
          groupDetails.value.push(detail);
        } else {
          expandDetails.value.push(detail);
        }
      });
    }

    const calcActionItemClass = (item: IDETBUIActionItem) => {
      const { actionLevel } = item;
      return [
        ns.e('item'),
        ns.is('disabled', false),
        ns.em('item', `level-${actionLevel}`),
      ];
    };

    watch(
      () => props.nodeData,
      async (newVal, oldVal) => {
        if (newVal !== oldVal) {
          await c.calcButtonState(
            newVal._deData || (newVal.srfkey ? newVal : undefined),
            props.nodeModel.appDataEntityId,
          );
        }
      },
    );

    c.evt.on('onCreated', async () => {
      await c.calcButtonState(
        props.nodeData._deData ||
          (props.nodeData.srfkey ? props.nodeData : undefined),
        props.nodeModel.appDataEntityId,
      );
    });

    // 点击事件抛给表格执行
    const handleClick = async (
      detail: IDETBUIActionItem,
      e: MouseEvent,
    ): Promise<void> => {
      e.stopPropagation();
      emit('action-click', detail, e);
    };

    return {
      c,
      ns,
      expandDetails,
      groupDetails,
      groupButtonRef,
      popoverVisible,
      handleClick,
      calcActionItemClass,
      actionDetails,
    };
  },
  render() {
    const details = this.actionDetails || [];

    const renderDivider = (isExpand: boolean) => {
      return (
        <el-divider
          class={this.ns.e('separator')}
          border-style='double'
          direction={isExpand ? 'vertical' : 'horizontal'}
        />
      );
    };

    const renderActions = (items: IDETBUIActionItem[], isExpand = true) => {
      return items.map(detail => {
        if (this.c.state.buttonsState[detail.id!]?.visible) {
          return [
            (detail as IAppDEUIActionGroupDetail).addSeparator &&
              renderDivider(isExpand),
            <el-button
              text
              size='small'
              onClick={(e: MouseEvent): Promise<void> =>
                this.handleClick(detail, e)
              }
              title={detail.tooltip}
              disabled={this.c.state.buttonsState[detail.id!].disabled}
              class={this.calcActionItemClass(detail)}
            >
              <div class={this.ns.e('action-content')}>
                {detail.showIcon && detail.sysImage && (
                  <div class={this.ns.e('action-content-icon')}>
                    <iBizIcon icon={detail.sysImage}></iBizIcon>
                  </div>
                )}

                {detail.showCaption ? (
                  <div class={this.ns.e('action-content-caption')}>
                    {detail.caption}
                  </div>
                ) : (
                  ''
                )}
              </div>
            </el-button>,
          ];
        }
        return null;
      });
    };

    if (this.mode === 'buttons') {
      // 按钮模式
      return (
        <div
          class={[this.ns.b(), this.ns.m('buttons')]}
          onClick={(e): void => e.stopPropagation()}
        >
          {renderActions(this.expandDetails)}
          {this.groupDetails.length > 0 && [
            <el-button
              size='small'
              text
              ref='groupButtonRef'
              class={[
                this.ns.e('item'),
                this.ns.is('expand', this.popoverVisible),
              ]}
            >
              {{
                icon: () => (
                  <ion-icon
                    class={this.ns.e('icon')}
                    name='ellipsis-vertical-outline'
                  />
                ),
              }}
            </el-button>,
            <el-popover
              placement='bottom-start'
              virtual-ref={this.groupButtonRef}
              trigger='click'
              v-model:visible={this.popoverVisible}
              popper-class={this.ns.e('popover')}
              virtual-triggering
            >
              {renderActions(this.groupDetails, false)}
            </el-popover>,
          ]}
        </div>
      );
    }
    // 下拉模式
    return (
      <el-dropdown
        onCommand={(command: IAppDEUIActionGroupDetail): Promise<void> =>
          this.handleClick(command, new MouseEvent('click'))
        }
        class={[this.ns.b(), this.ns.m('dropdown')]}
      >
        {{
          default: (): VNode => (
            <span class={this.ns.e('caption')}>
              <ion-icon
                class={this.ns.e('caption-icon')}
                name='ibiz-arrow-down'
              />
            </span>
          ),
          dropdown: (): VNode => (
            <el-dropdown-menu>
              {details.length > 0 &&
                details.map(detail => {
                  if (this.c.state.buttonsState[detail.id!]?.visible) {
                    return (
                      <el-dropdown-item
                        class={[
                          this.ns.e('item'),
                          this.ns.is('disabled', false),
                        ]}
                        title={detail.tooltip}
                        disabled={
                          this.c.state.buttonsState[detail.id!].disabled
                        }
                        command={detail}
                      >
                        {detail.showIcon && detail.sysImage && (
                          <iBizIcon icon={detail.sysImage}></iBizIcon>
                        )}
                        {detail.showCaption ? detail.caption : ''}
                      </el-dropdown-item>
                    );
                  }
                  return null;
                })}
            </el-dropdown-menu>
          ),
        }}
      </el-dropdown>
    );
  },
});
